package com.iconmaker.controller;

import afzkl.development.colorpickerview.dialog.ColorPickerDialog;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.BitmapDrawable;
import android.preference.PreferenceManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout.LayoutParams;

import com.bckim.iconmaker.R;
import com.iconmaker.command.BucketCommand;
import com.iconmaker.command.CommandManager;
import com.iconmaker.command.EraserCommand;
import com.iconmaker.command.PenCommand;
import com.iconmaker.model.Conf;
import com.iconmaker.model.State;
import com.iconmaker.util.EtcUtil;
import com.iconmaker.view.HScrollView;
import com.iconmaker.view.VScrollView;

public class CanvasEventListener implements OnClickListener, OnTouchListener {
	
	private CanvasActivity canvasActivity;
	private float touchStartX, touchStartY;
	private float currentX, currentY;
	private VScrollView vScrollView;
	private HScrollView hScrollView;
	private ImageView minimapView;
	private LinearLayout minimapPosition;
	
	private int pointerId;
	private int index;
	private double startTouchGap;
	private double tempGap;
	private int moveEventIndex;
	
	//colorPicker
	private final SharedPreferences prefs;
	private final ColorPickerDialog colorDialog;
	
	public CanvasEventListener(CanvasActivity context) {
		canvasActivity = context;
		vScrollView = (VScrollView)context.findViewById(R.id.vScroll);
		hScrollView = (HScrollView)context.findViewById(R.id.hScroll);
		minimapView = (ImageView)canvasActivity.findViewById(R.id.imgView_preview);
		minimapPosition = (LinearLayout)canvasActivity.findViewById(R.id.minimapPositionView);
		
		prefs = PreferenceManager.getDefaultSharedPreferences(context);
		colorDialog = new ColorPickerDialog(context, State.COLOR);
		colorDialog.setAlphaSliderVisible(true);
		colorDialog.setTitle("Pick a Color!");
	}
	
	public void onTouchEvent(MotionEvent event) {
		switch(event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN :
				EtcUtil.log("ACTION_DOWN");
				State.touchMode = State.TOUCH_MODE_WRITE;
				break;
			case MotionEvent.ACTION_MOVE :
				if(State.touchMode == State.TOUCH_MODE_SCROLL && event.getPointerCount() > 1) {
					index = event.findPointerIndex(pointerId);
					currentX = event.getX(index);
					currentY = event.getY(index);
					hScrollView.scrollBy((int)(touchStartX - currentX), (int)(touchStartY - currentY));
					vScrollView.scrollBy((int)(touchStartX - currentX), (int)(touchStartY - currentY));
					touchStartX = currentX;
					touchStartY = currentY;
					moveEventIndex = 0;
					refreshMinimap();
				}
				else if(State.touchMode == State.TOUCH_MODE_WRITE) {
					if(++moveEventIndex == 2) {
						if(State.writeMode == State.WRITE_MODE_PEN) {
							CommandManager.doCommand(new PenCommand(canvasActivity.getViewXIndex(event.getX()), canvasActivity.getViewYIndex(event.getY()), State.COLOR));
							moveEventIndex = 0;
						}
						else if(State.writeMode == State.WRITE_MODE_ERASER) {
							CommandManager.doCommand(new EraserCommand(canvasActivity.getViewXIndex(event.getX()), canvasActivity.getViewYIndex(event.getY())));
							moveEventIndex = 0;
						}
					}
				}
				
				break;
			case MotionEvent.ACTION_UP :
				EtcUtil.log("ACTION_UP");
				if(State.touchMode == State.TOUCH_MODE_WRITE) {
					write(event.getX(), event.getY());
				}
				
				refreshMinimap();
				
				break;
			case MotionEvent.ACTION_POINTER_DOWN :
				EtcUtil.log("ACTION_POINTER_DOWN");
				State.touchMode = State.TOUCH_MODE_SCROLL;
				pointerId = event.getPointerId(0);
				touchStartX = event.getX(0);
				touchStartY = event.getY(0);
				startTouchGap = getDistance(event);
				break;
			case MotionEvent.ACTION_POINTER_UP :
				EtcUtil.log("ACTION_POINTER_UP");
				if(State.touchMode == State.TOUCH_MODE_SCROLL && event.getPointerCount() > 1) {
					tempGap = getDistance(event) - startTouchGap;
					if(Math.abs(tempGap) > 5 && State.zoomLevel <= 1) {
						//						State.touchMode = State.TOUCH_MODE_ZOOM;
						//						
						//						State.zoomLevel = (float)(State.zoomLevel + (tempGap / 35)); 
						//						if(State.zoomLevel > 1)
						//							State.zoomLevel = 1f;
						//						
						//						pixcelContainerView.setScaleX(State.zoomLevel);
						//						pixcelContainerView.setScaleY(State.zoomLevel);
						//						
						//						EtcUtil.log("*width*" + pixcelContainerView.getWidth());
						//						EtcUtil.log("*height*" + pixcelContainerView.getHeight());
					}
					else {
						index = event.findPointerIndex(pointerId);
						currentX = event.getX(index);
						currentY = event.getY(index);
						vScrollView.scrollBy((int)(touchStartX - currentX), (int)(touchStartY - currentY));
						hScrollView.scrollBy((int)(touchStartX - currentX), (int)(touchStartY - currentY));
						refreshMinimap();
					}
				}
				
				break;
		}
	}
	
	private void write(float x, float y) {
		if(State.writeMode == State.WRITE_MODE_PEN)
			CommandManager.doCommand(new PenCommand(canvasActivity.getViewXIndex(x), canvasActivity.getViewYIndex(y), State.COLOR));
		else if(State.writeMode == State.WRITE_MODE_BUCKET)
			CommandManager.doCommand(new BucketCommand(canvasActivity.getViewXIndex(x), canvasActivity.getViewYIndex(y), State.COLOR));
		else if(State.writeMode == State.WRITE_MODE_ERASER)
			CommandManager.doCommand(new EraserCommand(canvasActivity.getViewXIndex(x), canvasActivity.getViewYIndex(y)));
	}
	
	@Override
	public void onClick(final View v) {
		switch(v.getId()) {
			case R.id.penPickerBtn :
				State.writeMode = State.WRITE_MODE_PEN;
				((ImageButton)v).setBackgroundResource(R.drawable.icon_pencil_focus);
				((ImageButton)canvasActivity.findViewById(R.id.bucketBtn)).setBackgroundResource(R.drawable.icon_bucket);
				((ImageButton)canvasActivity.findViewById(R.id.eraserBtn)).setBackgroundResource(R.drawable.icon_eraser);
				break;
			
			case R.id.bucketBtn :
				State.writeMode = State.WRITE_MODE_BUCKET;
				((ImageButton)v).setBackgroundResource(R.drawable.icon_bucket_focus);
				((ImageButton)canvasActivity.findViewById(R.id.penPickerBtn)).setBackgroundResource(R.drawable.icon_pencil);
				((ImageButton)canvasActivity.findViewById(R.id.eraserBtn)).setBackgroundResource(R.drawable.icon_eraser);
				break;
			case R.id.eraserBtn :
				State.writeMode = State.WRITE_MODE_ERASER;
				((ImageButton)v).setBackgroundResource(R.drawable.icon_eraser_focus);
				((ImageButton)canvasActivity.findViewById(R.id.penPickerBtn)).setBackgroundResource(R.drawable.icon_pencil);
				((ImageButton)canvasActivity.findViewById(R.id.bucketBtn)).setBackgroundResource(R.drawable.icon_bucket);
				break;
			case R.id.colorPickerBtn :
				colorDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						//Save the value in our preferences.
						SharedPreferences.Editor editor = prefs.edit();
						editor.putInt("color_2", colorDialog.getColor());
						editor.commit();
						
						State.COLOR = colorDialog.getColor();
						
						((ImageButton)((Activity)v.getContext()).findViewById(R.id.colorPickerBtn)).setColorFilter(State.COLOR, Mode.MULTIPLY);
					}
				});
				
				colorDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {}
				});
				
				colorDialog.show();
				
				break;
			
			case R.id.undoBtn :
				CommandManager.unDo();
				refreshMinimap();
				break;
			case R.id.redoBtn :
				CommandManager.reDo();
				refreshMinimap();
				break;
			case R.id.importBtn :
				CanvasActivity.getContext().getImage();
				refreshMinimap();
				break;
			case R.id.exportBtn :
				DataManager.share();
				break;
		}
	}
	
	public double getDistance(MotionEvent event) {
		return Math.sqrt(Math.abs(event.getX(0) - event.getX(1)) + Math.abs(event.getY(0) - event.getY(1)));
	}
	
	public void refreshMinimap() {
		Bitmap bitmap = Bitmap.createBitmap(Conf.countOfColumnPixcel, Conf.countOfRowPixcel, Bitmap.Config.ARGB_8888);
		
		for(int i = 0; i < Conf.countOfRowPixcel; i++) {
			for(int j = 0; j < Conf.countOfColumnPixcel; j++) {
				bitmap.setPixel(i, j, State.canvasState[i][j]);
			}
		}
		
		minimapView.setBackgroundDrawable(new BitmapDrawable(canvasActivity.getResources(), Bitmap.createScaledBitmap(bitmap, Conf.countOfColumnPixcel * 3, Conf.countOfColumnPixcel * 3, false)));
		
		if(State.minimapHeightRatio != 0 && State.minimapWidthRatio != 0) {
			LayoutParams params = new LayoutParams(minimapPosition.getWidth(), minimapPosition.getHeight());
			params.setMargins(hScrollView.getScrollX() / State.minimapWidthRatio, vScrollView.getScrollY() / State.minimapHeightRatio, 0, 0);
			minimapPosition.setLayoutParams(params);
		}
		
		bitmap.recycle();
	}
	
	private float miniTouchStartX, miniTouchStartY;
	private float miniCurrentX, miniCurrentY;
	
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		LayoutParams params;
		switch(event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN :
				EtcUtil.log("ACTION_DOWN");
				miniTouchStartX = event.getX();
				miniTouchStartY = event.getY();
				
				break;
			case MotionEvent.ACTION_MOVE :
				EtcUtil.log("ACTION_MOVE");
				miniCurrentX = event.getX();
				miniCurrentY = event.getY();
				
				vScrollView.scrollBy((int)(miniCurrentX - miniTouchStartX), (int)(miniCurrentY - miniTouchStartY));
				hScrollView.scrollBy((int)(miniCurrentX - miniTouchStartX), (int)(miniCurrentY - miniTouchStartY));
				
				miniCurrentX = miniTouchStartX;
				miniCurrentY = miniTouchStartY;
				break;
			case MotionEvent.ACTION_UP :
				EtcUtil.log("ACTION_UP");
				miniCurrentX = event.getX();
				miniCurrentY = event.getY();
				
				vScrollView.scrollBy((int)(miniCurrentX - miniTouchStartX), (int)(miniCurrentY - miniTouchStartY));
				hScrollView.scrollBy((int)(miniCurrentX - miniTouchStartX), (int)(miniCurrentY - miniTouchStartY));
				
				break;
		
		}
		
		refreshMinimap();
		
		return true;
	}
}
